home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr47 / a_code01.zip / DB_WINL.ASM < prev   
Assembly Source File  |  1993-04-07  |  17KB  |  657 lines

  1. dosseg
  2. locals
  3.  
  4. .model    large
  5.  
  6. extrn    _checksnow:byte
  7. extrn    _scrwid:byte
  8. extrn    _scrhgt:byte
  9. extrn    _cmono:dword
  10.  
  11. .code
  12.  
  13. public    _dispw
  14. public    _initblk
  15. public    _restline
  16. public    _displine
  17. public    _dispattr
  18.  
  19. ;-----------------------------------------------------------------------------
  20. ; MACRO TO TRANSLATE MONO ATTRIBUTE
  21. ;-----------------------------------------------------------------------------
  22. reset_attrib    macro
  23.         push    es
  24.         push    di
  25.         push    ax
  26.         les    di,dword ptr cs:tomonoofs
  27.         mov    al,ah
  28.         xor    ah,ah
  29.         add    di,ax
  30.         pop    ax
  31.         mov    ah,es:[di]
  32.         pop    di
  33.         pop    es
  34.         endm
  35.  
  36. ;-----------------------------------------------------------------------------
  37. ; LOCAL STORAGE FOR ATTRIBUTE TRANSLATE TABLE ADDRESS
  38. ;-----------------------------------------------------------------------------
  39. tomonoofs    dw    0
  40. tomonobase    dw    0
  41.  
  42. ;-----------------------------------------------------------------------------
  43. ; WRITE CHARACTER TO VIDEO RAM WITH RETRACE SYNCH
  44. ;-----------------------------------------------------------------------------
  45. ; Writes the char/attr specified to video ram synching to the horizintal
  46. ; and vertical retrace on CGA.
  47. ; Attributes and characters of 0 are not written.
  48. ;
  49. ; Input:
  50. ;  AX - char/attr to write
  51. ;  ES:DI - video ram destination address
  52. ;
  53. ; Output:
  54. ;  ES:DI - just past word written
  55. ;
  56. ; Destroys:
  57. ;  None
  58. ;
  59. ;-----------------------------------------------------------------------------
  60. vidchr        proc    near
  61.         push    bp
  62.         push    dx
  63.         mov    dx,3DAh            ; address CGA status port
  64.         mov    bp,ax            ; save char/attr
  65.         or    ah,ah            ; is attribute is zero
  66.         je    @@charonly        ; y - only output the char
  67.         or    al,al            ; is char NUL
  68.         je    @@attronly        ; y - only output the attr
  69.  
  70. @@charattr:                    ; WRITE CHARACTER/ATTRIBUTE
  71. @@cawait1:    in    al,dx            ; wait for horz retrace to
  72.         rcr    al,1            ; ensure proper synch
  73.         jnb    @@cawait1
  74. @@cawait2:    in    al,dx            ; wait for no horz retrace
  75.         and    al,9            ; or vert retrace
  76.         shr    al,1
  77.         jnz    @@cawrite
  78.         jb    @@cawait2
  79.         cli
  80. @@cawait3:    in    al,dx            ; wait for retrace
  81.         rcr    al,1
  82.         jnb    @@cawait3
  83. @@cawrite:    mov    ax,bp            ; store word
  84.         stosw
  85.         sti
  86.         jmp    short @@fin
  87.  
  88. @@charonly:                    ; WRITE CHARACTER ONLY
  89. @@cowait1:    in    al,dx            ; wait for horz retrace to
  90.         rcr    al,1            ; ensure proper synch
  91.         jnb    @@cowait1
  92. @@cowait2:    in    al,dx            ; wait for no horz retrace
  93.         and    al,9            ; or vert retrace
  94.         shr    al,1
  95.         jnz    @@cowrite
  96.         jb    @@cowait2
  97.         cli
  98. @@cowait3:    in    al,dx            ; wait for retrace
  99.         rcr    al,1
  100.         jnb    @@cowait3
  101. @@cowrite:    mov    ax,bp            ; store character
  102.         stosb
  103.         sti
  104.         inc    di            ; skip attribute
  105.         jmp    short @@fin
  106.  
  107. @@attronly:                    ; WRITE ATTRIBUTE ONLY
  108. @@aowait1:    in    al,dx            ; wait for horz retrace to
  109.         rcr    al,1            ; ensure proper synch
  110.         jnb    @@aowait1
  111. @@aowait2:    in    al,dx            ; wait for no horz retrace
  112.         and    al,9            ; or vert retrace
  113.         shr    al,1
  114.         jnz    @@aowrite
  115.         jb    @@aowait2
  116.         cli
  117. @@aowait3:    in    al,dx            ; wait for retrace
  118.         rcr    al,1
  119.         jnb    @@aowait3
  120. @@aowrite:    mov    ax,bp            ; store attribute
  121.         inc    di            ; skip character
  122.         mov    es:[di],ah
  123.         sti
  124.         inc    di            ; move to next char
  125.  
  126. @@fin:        pop    dx
  127.         pop    bp
  128.         ret
  129. vidchr        endp
  130.  
  131. ;-----------------------------------------------------------------------------
  132. ; WRITE STRING TO VIDEO RAM WITH RETRACE SYNCH
  133. ;-----------------------------------------------------------------------------
  134. ; Writes the char/attrs specified to video ram synching to the horizintal
  135. ; and vertical retrace on CGA.
  136. ;
  137. ; Input:
  138. ;  CX - number of words to write
  139. ;  DS:SI - source address
  140. ;  ES:DI - video ram destination address
  141. ;
  142. ; Output:
  143. ;  DS:SI - just past last word read
  144. ;  ES:DI - just past last word written
  145. ;  CX - 0
  146. ;
  147. ; Destroys:
  148. ;  None
  149. ;
  150. ;-----------------------------------------------------------------------------
  151. vidstr        proc    near
  152.         push    bp
  153.         push    ax
  154.         push    dx
  155.         mov    dx,3DAh            ; address CGA status port
  156.  
  157. @@wait0:    in    al,dx            ; wait for horz retrace to
  158.         rcr    al,1            ; ensure proper synch
  159.         jnb    @@wait0
  160.  
  161. @@writeloop:    lodsw                ; get char/attr
  162.         mov    bp,ax            ; save word to write
  163.  
  164. @@wait1:    in    al,dx            ; wait for no horz retrace
  165.         and    al,9            ; or vert retrace
  166.         shr    al,1
  167.         jnz    @@write
  168.         jb    @@wait1
  169.         cli
  170.  
  171. @@wait2:    in    al,dx            ; wait for retrace
  172.         rcr    al,1
  173.         jnb    @@wait2
  174.  
  175. @@write:    mov    ax,bp            ; store word
  176.         stosw
  177.         sti
  178.         loop    @@writeloop
  179.  
  180.         pop    dx
  181.         pop    ax
  182.         pop    bp
  183.         ret
  184. vidstr        endp
  185.  
  186. ;-----------------------------------------------------------------------------
  187. ; void dispw(byte x, byte y, byte w, byte h, byte _w, ptr vram, ptr winb);
  188. ;-----------------------------------------------------------------------------
  189. ; Displays window buffer contents on video ram
  190. ;
  191. ;-----------------------------------------------------------------------------
  192. _dispw        proc
  193. arg x:byte, y:byte, w:byte, h:byte, _w:byte, vram:dword, winb:dword
  194.         push    bp
  195.         mov    bp,sp            ; link stack
  196.         push    si            ; save regs
  197.         push    di
  198.         push    ds
  199.         mov    ax,seg _cmono        ; put attribute base in local
  200.         mov    ds,ax            ; storage in CS:
  201.         les    di,_cmono
  202.         mov    cs:tomonobase,es
  203.         mov    cs:tomonoofs,di
  204.         les    di,vram            ; get video ram addr
  205.         mov    bx,es
  206.         xor    bx,0B800h        ; check for CGA screen dest
  207.         jnz    @@nosnowcheck        ; n - ignore checksnow
  208.         mov    ax,seg _checksnow
  209.         mov    ax,ds
  210.         mov    bl,_checksnow        ; load checksnow value
  211.         xor    bh,bh
  212.         jmp    short @@snowchecked    ; go do
  213.  
  214. @@nosnowcheck:    xor     bx,bx
  215.  
  216. @@snowchecked:    push    bx            ; save synch flag on stack
  217.         mov    ax,seg _scrwid        ; get video screen width
  218.         mov    ds,ax
  219.         mov    al,_scrwid
  220.         xor    ah,ah
  221.         shl    ax,1            ; take attributes into account
  222.         push    ax            ; save width on stack
  223.         lds    si,winb            ; DS:SI = window block address
  224.         mov    dl,x
  225.         dec    dl            ; DL = x-1 zero ofs
  226.         mov    dh,y
  227.         dec    dh            ; DH = y-1
  228.         mul    dh            ; calc location vram ofs
  229.         add    al,dl            ; add in col ofs
  230.         adc    ah,+00
  231.         add    al,dl
  232.         adc    ah,+00
  233.         mov    di,ax            ; ES:DI dest in video ram
  234.         mov    cl,w
  235.         xor    ch,ch            ; CX = displayable chars/line
  236.         mov    dl,h            ; DL = displayable lines
  237.         pop    ax            ; get screen width off stack
  238.         sub    al,cl
  239.         sub    al,cl
  240.         xor    ah,ah            ; AX = next line vram inc
  241.         mov    bl,_w
  242.         shl    bl,1
  243.         xor    bh,bh            ; BX = next line winb inc
  244.         cld                ; go forwards
  245.         pop    bp            ; BP = synch flag
  246.         jcxz    @@fin            ; exit if no lines to do
  247.         or    dl,dl            ; see is any lines to do
  248.         jz    @@fin            ; n - nothing to do
  249.  
  250. @@disploop:    push    cx            ; save chars/line
  251.         or    bp,bp            ; check for synch required
  252.         jz    @@nosnow        ; n
  253.  
  254. @@snow:        call    vidstr            ; y - avoid snow
  255.         jmp    short @@skip
  256.  
  257. @@nosnow:    push    ax            ; save vram inc
  258. @@repeat:    lodsw                ; get buffer word
  259.         reset_attrib
  260.         stosw                ; store to vram
  261.         loop    @@repeat        ; repeat for all chars/line
  262.         pop    ax            ; get vram inc
  263.  
  264. @@skip:        add    si,bx            ; move to next winb line
  265.         add    di,ax            ; move to next vram line
  266.         pop    cx            ; restore chars/line
  267.         dec    dl            ; reduce lines to do
  268.         ja    @@disploop        ; continue for all lines
  269.  
  270. @@fin:        pop    ds            ; restore regs
  271.         pop    di
  272.         pop    si
  273.         pop    bp
  274.         ret
  275. _dispw        endp
  276.  
  277. ;-----------------------------------------------------------------------------
  278. ; void initblk(word len, char chr, byte color, ptr winb);
  279. ;-----------------------------------------------------------------------------
  280. ; Fills window buffer with specified char and attribute
  281. ;
  282. ;-----------------------------------------------------------------------------
  283. _initblk    proc
  284. arg len:word,chr:byte,color:byte,winb:dword
  285.         push    bp
  286.         mov    bp,sp            ; link stack
  287.         push    si            ; save regs
  288.         push    di
  289.         push    ds
  290.         les    di,winb            ; ES:DI = window block addr
  291.         mov    al,chr
  292.         mov    ah,color
  293.         mov    cx,len
  294.         jcxz    @@fin
  295.         cld                ; go forwards
  296.         rep    stosw            ; fill window buffer
  297. @@fin:        pop    ds            ; restore regs
  298.         pop    di
  299.         pop    si
  300.         pop    bp
  301.         ret
  302. _initblk    endp
  303.  
  304. ;-----------------------------------------------------------------------------
  305. ; void restline(byte x, byte y, byte len, byte orient, ptr actv, ptr savv);
  306. ;-----------------------------------------------------------------------------
  307. ; Transfers line from save video to active video in orientation specified
  308. ;
  309. ;-----------------------------------------------------------------------------
  310. _restline    proc
  311. arg x:byte,y:byte,len:byte,orient:byte,actv:dword,savv:dword
  312.         push    bp
  313.         mov    bp,sp            ; link stack
  314.         push    si            ; save regs
  315.         push    di
  316.         push    ds
  317.         mov    ax,seg _cmono        ; put attribute base in local
  318.         mov    ds,ax            ; storage in CS:
  319.         les    di,_cmono
  320.         mov    cs:tomonobase,es
  321.         mov    cs:tomonoofs,di
  322.         mov    ax,seg _scrwid        ; get video screen width
  323.         mov    ds,ax
  324.         mov    al,_scrwid
  325.         xor    ah,ah
  326.         shl    ax,1            ; AX = video ram width
  327.         push    ax            ; save on stack
  328.         mov    bx,seg _checksnow    ; get synch flag
  329.         mov    ds,bx
  330.         mov    bl,_checksnow
  331.         xor    bh,bh            ; BX = synch flag
  332.         push    bx            ; save on stack
  333.         les    di,actv            ; ES:DI = active video base
  334.         lds    si,savv            ; DS:SI = save video base
  335.         mov    dl,x
  336.         dec    dl            ; DL = x-1 zero ofs
  337.         mov    dh,y
  338.         dec    dh            ; DH = y-1
  339.         mul    dh            ; calc location ofs
  340.         add    al,dl
  341.         adc    ah,0
  342.         add    al,dl
  343.         adc    ah,0
  344.         mov    di,ax            ; ES:DI = active video loc
  345.         mov    si,ax            ; DS:SI = save video loc
  346.         cld                ; go forwards
  347.         mov    bl,orient
  348.         xor    bh,bh
  349.         mov    cl,len
  350.         xor    ch,ch
  351.         or    cx,cx            ; any to do
  352.         jnz    @@sometodo        ; y
  353.         pop    ax            ; cleanup stack
  354.         pop    ax
  355.         jmp    short @@fin
  356.  
  357. @@sometodo:    pop     bp            ; get synch flag
  358.         shr    bx,1            ; check direction
  359.         jb    @@horizontal        ; go horizontally
  360.  
  361. @@vertical:    pop    bx            ; get width
  362.         sub    bx,2
  363.  
  364. @@vwriteloop:    lodsw
  365.         or    bp,bp
  366.         jz      @@vnosnow
  367.  
  368. @@vsnow:    call    vidchr            ; CGA interference avoidance
  369.         jmp    short @@vskip
  370.  
  371. @@vnosnow:    reset_attrib
  372.         stosw
  373.  
  374. @@vskip:    add    di,bx
  375.         add    si,bx
  376.         loop    @@vwriteloop
  377.         jmp    short @@fin
  378.  
  379. @@horizontal:    or    bp,bp            ; check synch flag
  380.         jz    @@hnosnow
  381.  
  382. @@hsnow:    call    vidstr            ; CGA interference avoidance
  383.         jmp    short @@hskip
  384.  
  385. @@hnosnow:    lodsw
  386.         reset_attrib
  387.         stosw
  388.         loop    @@hnosnow
  389.  
  390. @@hskip:    pop    bx            ; width still on stack
  391.  
  392. @@fin:        pop    ds            ; restore regs
  393.         pop    di
  394.         pop    si
  395.         pop    bp
  396.         ret
  397. _restline    endp
  398.  
  399. ;-----------------------------------------------------------------------------
  400. ; DETERMINE STRING LENGTH
  401. ;-----------------------------------------------------------------------------
  402. ; Input:
  403. ;  DS:SI - pointer to string
  404. ; Output:
  405. ;  CX - string length
  406. ; Destroys:
  407. ;  none
  408. ;
  409. ;-----------------------------------------------------------------------------
  410. strlen        proc    near
  411.         push    si
  412.         xor    cx,cx            ; init to empty string
  413. @@loop:        cmp    byte ptr ds:[si],0    ; is char NUL
  414.         je    @@fin            ; y - done
  415.         inc    cx            ; bump char count
  416.         inc    si            ; bump char pointer
  417.         jmp    short @@loop        ; keep going
  418.  
  419. @@fin:        pop    si
  420.         ret
  421. strlen        endp
  422.  
  423. ;-----------------------------------------------------------------------------
  424. ; void displine(byte x, byte y, byte colr, byte orient, byte w, word _di,
  425. ;               ptr destv, ptr s);
  426. ;-----------------------------------------------------------------------------
  427. ; Writes string to video buffer in orientation specified
  428. ;
  429. ;-----------------------------------------------------------------------------
  430. _displine    proc
  431. arg x:byte,y:byte,colr:byte,orient:byte,w:byte,_di:word,destv:dword,s:dword
  432.         push    bp
  433.         mov    bp,sp            ; link stack
  434.         push    si            ; save regs
  435.         push    di
  436.         push    ds
  437.         les    di,destv        ; ES:DI - dest video base
  438.         mov    bx,es
  439.         xor    bx,0B800h        ; is dest in CGA ram
  440.         jnz    @@nosnowcheck        ; n - so ignore checksnow
  441.         mov    bx,seg _checksnow
  442.         mov    bl,_checksnow        ; load checksnow value
  443.         xor    bh,bh
  444.         jmp    short @@snowchecked
  445.  
  446. @@nosnowcheck:    xor    bx,bx
  447.  
  448. @@snowchecked:    mov    ax,_di            ; get max window _di
  449.         push    ax            ; save on stack
  450.         push    bx            ; save synch flag on stack
  451.         mov    al,w
  452.         xor    ah,ah
  453.         shl    ax,1            ; AX - width in video ram
  454.         push    ax            ; save for with vert lines
  455.         lds    si,s            ; DS:SI - source string
  456.         mov    dl,x
  457.         dec    dl            ; DL = x-1  zero ofs
  458.         mov    dh,y
  459.         dec    dh            ; DH = y-1
  460.         mul    dh            ; calc location ofs
  461.         add    al,dl
  462.         adc    ah,0
  463.         add    al,dl
  464.         adc    ah,0
  465.         mov    di,ax            ; ES:DI - dest ofs
  466.         cld                ; go forwards
  467.         call    strlen            ; get string length
  468.         or    cx,cx            ; any chars to do
  469.         jnz    @@sometodo
  470.         pop    ax            ; cleanup stack
  471.         pop    ax
  472.         pop    ax
  473.         jmp    @@finnocx
  474.  
  475. @@sometodo:    mov    bl,orient        ; BX = orientation
  476.         xor    bh,bh
  477.         shr    bx,1
  478.         jb    @@horizontal
  479.  
  480. @@vertical:    pop    bx            ; get window width off stack
  481.         sub    bx,2
  482.         jmp    short @@setup
  483.  
  484. @@horizontal:    pop    ax            ; get window width off stack
  485.  
  486. @@setup:    mov    al,[si]            ; first character
  487.         mov    ah,colr            ; AH = color
  488.         pop    dx            ; DX = synch flag
  489.         pop    bp            ; BP = max screen size
  490.  
  491. @@test255:    cmp    al,0FFh            ; check for special chars
  492.         jne    @@outchar        ; n
  493.         dec    cx
  494.         inc    si
  495.         mov    al,[si]
  496.         cmp    cx,3            ; enough chars for contol code
  497.         jb    @@fin            ; n - exit
  498.         cmp    al,2            ; 2 = change attribute
  499.         je    @@changeattr
  500.         cmp    al,1            ; 1 = repeat character
  501.         je    @@repeatchar
  502.         jmp    short @@outchar
  503.  
  504. @@changeattr:    inc    si
  505.         mov    ah,[si]            ; new attribute
  506.         inc    si
  507.         mov    al,[si]            ; next character into AL
  508.         sub    cx,2
  509.         jmp    short @@test255        ; see if char is control code
  510.  
  511. @@repeatchar:    sub    cx,2
  512.         push    cx            ; save count
  513.         mov    dh,1            ; show in repeat
  514.         inc    si
  515.         mov    cl,[si]            ; get count
  516.         inc    si
  517.         mov    al,[si]            ; get char
  518.         xor    ch,ch
  519.         jcxz    @@skip            ; aviod a zero repeat count
  520.  
  521. @@outchar:    or    dl,dl            ; see if avoid snow
  522.         jz    @@nosnow        ; n
  523.  
  524. @@snow:        call    vidchr            ; CGA interference avoidance
  525.         jmp    short @@skip
  526.  
  527. @@nosnow:    or    ah,ah            ; see if attrib supplied
  528.         jz    @@charonly        ; n - output character only
  529.         or    al,al            ; see if character supplied
  530.         jz      @@attronly        ; n - output attrribute only
  531.  
  532. @@charattr:    stosw                ; output the char & attr pair
  533.         jmp    short @@skip
  534.  
  535. @@charonly:    stosb
  536.         inc    di            ; step past screen attr
  537.         jmp    short @@skip
  538.  
  539. @@attronly:    inc    di            ; step past screen char
  540.         mov    es:[di],ah        ; put only the attr
  541.         inc    di            ; move on to next char
  542.  
  543. @@skip:        add    di,bx            ; add in width for vert
  544.         cmp    bp,di
  545.         jbe    @@fin            ; at end of window so stop
  546.         or    dh,dh            ; is this a rep print
  547.         jz    @@normal        ; n
  548.         cmp    cx,1            ; y
  549.         jle    @@repeatfin
  550.         loop    @@outchar
  551. @@repeatfin:    pop    cx
  552.         xor    dh,dh
  553.  
  554. @@normal:    inc    si            ; point to next char to disp
  555.         mov    al,[si]            ; get char into AL
  556.         loop    @@test255
  557.  
  558. @@fin:        or    dh,dh            ; is cx still on stack
  559.         jz    @@finnocx        ; n
  560.         pop    cx            ; y - get it off
  561. @@finnocx:    pop    ds            ; restore regs
  562.         pop    di
  563.         pop    si
  564.         pop    bp
  565.         ret
  566. _displine    endp
  567.  
  568. ;-----------------------------------------------------------------------------
  569. ; void dispattr(byte x, byte y, byte colr, byte orient, byte w, word _di,
  570. ;               ptr destv, byte n);
  571. ;-----------------------------------------------------------------------------
  572. ; Sets attribute on number of characters specified
  573. ;
  574. ;-----------------------------------------------------------------------------
  575. _dispattr    proc
  576. arg x:byte,y:byte,colr:byte,orient:byte,w:byte,_di:word,destv:dword,n:byte
  577.         push    bp
  578.         mov    bp,sp            ; link stack
  579.         push    di
  580.         les    di,destv        ; ES:DI - dest video base
  581.         mov    bx,es
  582.         xor    bx,0B800h        ; is dest in CGA ram
  583.         jnz    @@nosnowcheck        ; n - so ignore checksnow
  584.         mov    bx,seg _checksnow
  585.         mov    bl,_checksnow        ; load checksnow value
  586.         xor    bh,bh
  587.         jmp    short @@snowchecked
  588.  
  589. @@nosnowcheck:    xor    bx,bx
  590.  
  591. @@snowchecked:    mov    ax,_di            ; get max window _di
  592.         push    ax            ; save on stack
  593.         push    bx            ; save synch flag on stack
  594.         mov    al,w
  595.         xor    ah,ah
  596.         shl    ax,1            ; AX - width in video ram
  597.         push    ax            ; save for with vert lines
  598.         mov    dl,x
  599.         dec    dl            ; DL = x-1  zero ofs
  600.         mov    dh,y
  601.         dec    dh            ; DH = y-1
  602.         mul    dh            ; calc location ofs
  603.         add    al,dl
  604.         adc    ah,0
  605.         add    al,dl
  606.         adc    ah,0
  607.         mov    di,ax            ; ES:DI - dest ofs
  608.         cld                ; go forwards
  609.         mov    cl,n
  610.         xor    ch,ch
  611.         or    cx,cx            ; any to do
  612.         jnz    @@sometodo
  613.         pop    ax            ; cleanup stack
  614.         pop    ax
  615.         pop    ax
  616.         jmp    @@fin
  617.  
  618. @@sometodo:    mov    bl,orient        ; BX = orientation
  619.         xor    bh,bh
  620.         shr    bx,1
  621.         jb    @@horiz
  622.  
  623. @@vert:        pop    bx            ; get window width off stack
  624.         sub    bx,2
  625.         jmp    short @@setup
  626.  
  627. @@horiz:    pop    ax            ; get window width off stack
  628.  
  629. @@setup:    mov    al,0            ; AL = NUL - dont write chars
  630.         mov    ah,colr            ; AH = color
  631.         pop    dx            ; DX = synch flag
  632.         pop    bp            ; BP = max screen size
  633.  
  634. @@outattr:    or    dl,dl            ; see if avoid snow
  635.         jz    @@nosnow        ; n
  636.  
  637. @@snow:        call    vidchr            ; CGA interference avoidance
  638.         jmp    short @@skip
  639.  
  640. @@nosnow:    inc    di            ; step past screen char
  641.         mov    es:[di],ah        ; put only the attr
  642.         inc    di            ; move on to next char
  643.  
  644. @@skip:        add    di,bx            ; add in width for vert
  645.         cmp    bp,di
  646.         jbe    @@fin            ; at end of window so stop
  647.         loop    @@outattr
  648.  
  649. @@fin:        pop    di
  650.         pop    bp
  651.         ret
  652. _dispattr    endp
  653.  
  654. ;-----------------------------------------------------------------------------
  655.  
  656. end
  657.